package com.mxpio.erp.equipment.job;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.mxpio.erp.common.equipment.entity.*;
import com.mxpio.erp.common.equipment.service.*;
import com.mxpio.erp.equipment.utils.OrderNumberUtil;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

/**
 * @Classname GenTaskJob
 * @Description 生成保养任务JOB
 */
@Slf4j
@Component
@Configurable
@EnableScheduling
public class GenUpkeepTaskJob {

    @Autowired
    private EquipmentUpkeepPlanService tpmUpkeepPlanService;
    @Autowired
    private EquipmentUpkeepPlanTargetService tpmUpkeepPlanTargetService;
    @Autowired
    private EquipmentUpkeepPlanDetailService tpmUpkeepPlanDetailService;
    @Autowired
    private EquipmentUpkeepPlanDetailParamService tpmUpkeepPlanDetailParamService;
    @Autowired
    private EquipmentUpkeepTaskService tpmUpkeepTaskService;
    @Autowired
    private EquipmentUpkeepTaskDetailService tpmUpkeepTaskDetailService;
    @Autowired
    private EquipmentUpkeepTaskDetailParamService tpmUpkeepTaskDetailParamService;

    public static final Integer STATUS_START = 10;


    /**
     * 根据保养计划生成任务（每天晚上零点五分）
     */
    //@Scheduled(cron = "0 5 0 * * ?")
    public void executeGenUpkeepTaskJob(){
        log.info(" --- 生成保养任务调度开始 --- ");

        // 查询出要生成保养任务的计划
        /**
         * 查询条件：
         * 1.需要enable的
         * 2.上次计划开始时间之前的（<=）
         * 3.新增计划默認的是创建时间，所以可以使用第二条判断条件
         */
        Criteria c = Criteria.create().addCriterion("isEnable", Operator.EQ, 1);
        c.addCriterion("lastPlanStart", Operator.LE, new Date());
        List<EquipmentUpkeepPlan> list = tpmUpkeepPlanService.list(EquipmentUpkeepPlan.class,c);


        /**
         * 计划时间计算：
         * 1.组装计划开始时间
         * 1.1 获取开始时间单位，根据时间单位获取当前时间前缀，例如“时”，则时间前缀为2021-10-08 ，“分”则时间前缀为"2021-10-08 10:"
         * 1.2 根据开始时间和频率和频率单位，计算出结束时间
         * 1.3 判断下次开始时间是否超过今日24点，没超过就继续生成本条计划内的任务，超过就不再生成
         */
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        Date tomorrow = DateUtil.tomorrow();
        String formatToday = DateUtil.format(new Date(), "yyyy-MM-dd");
        list.forEach(plan -> {
            // 获取今日第一条任务
            String formatPlanStartTime = formatToday + " " + plan.getStartTime();
            DateTime firstPlanStartTime = DateUtil.parse(formatPlanStartTime);
            Date prePlanStartTime = firstPlanStartTime;
            while (true) {
                // 获取频率，并计算出计划结束时间
                Date nextPlanStartTime = null;
                switch (plan.getRateUnit()) {
                    case "分":
                        nextPlanStartTime = DateUtils.addMinutes(prePlanStartTime, Integer.valueOf(plan.getRate()));
                        break;
                    case "时":
                        nextPlanStartTime = DateUtils.addHours(prePlanStartTime, Integer.valueOf(plan.getRate()));
                        break;
                    case "月":
                        nextPlanStartTime = DateUtils.addMonths(prePlanStartTime, Integer.valueOf(plan.getRate()));
                        break;
                    case "年":
                        nextPlanStartTime = DateUtils.addYears(prePlanStartTime, Integer.valueOf(plan.getRate()));
                        break;
                }


                // 获取保养计划目标
                List<EquipmentUpkeepPlanTarget> targets = tpmUpkeepPlanTargetService.selectByMainId(plan.getId());
                if (CollectionUtils.isEmpty(targets)) {
                    break;
                }

                // 获取保养明细
                List<EquipmentUpkeepPlanDetail> planDetails = tpmUpkeepPlanDetailService.selectByMainId(plan.getId());
                if (CollectionUtils.isEmpty(planDetails)) {
                    break;
                }

                // 赋值task信息
                for (int i = 0; i < targets.size(); i++) {
                    EquipmentUpkeepPlanTarget target = targets.get(i);
                    EquipmentUpkeepTask task = new EquipmentUpkeepTask();
                    task.setOrderCode(OrderNumberUtil.getCode("C"));
                    task.setOrderStatus(STATUS_START);
                    task.setTargetType(plan.getTargetType());
                    task.setTargetCode(target.getTargetCode());
                    task.setTargetName(target.getTargetName());
                    task.setTargetId(target.getTargetId());
                    task.setTargetSpec(target.getTargetSpec());
                    task.setIsAutoRelease(plan.getIsAuto());
                    task.setPlanStartTime(prePlanStartTime);
                    task.setPlanEndTime(nextPlanStartTime);
                    task.setDispatchMode(plan.getDispatchMode());
                    task.setReleaseTargetType(plan.getReleaseTargetType());
                    task.setReleaseTargetId(plan.getTarget());
                    task.setReleaseTargetName(plan.getTargetName());
                    if (task.getIsAutoRelease() == 1) {
                        task.setPlanReleaseTime(DateUtils.addMinutes(task.getPlanStartTime(),0-plan.getAdvanceTime()));
                    }
                    task.setCreateTime(new Date());
                    task.setCreateBy("系统生成");

                    // 赋值taskDetail信息
                    tpmUpkeepTaskService.save(task);
                    for (int i1 = 0; i1 < planDetails.size(); i1++) {
                        EquipmentUpkeepTaskDetail taskDetail = new EquipmentUpkeepTaskDetail();
                        BeanUtils.copyProperties(planDetails.get(i1), taskDetail, "id","createTime","createBy","updateTime","updateBy","updateTime","sysOrgCode");
                        taskDetail.setTaskId(task.getId());
                        taskDetail.setCreateBy("系统生成");
                        tpmUpkeepTaskDetailService.save(taskDetail);
                        if (taskDetail.getChooseEnable() == 1) {
                            // 如果有选项，则获取选项
                            List<EquipmentUpkeepPlanDetailParam> planDetailParams = tpmUpkeepPlanDetailParamService.selectByMainId(planDetails.get(i1).getId());
                            if (!CollectionUtils.isEmpty(planDetailParams)) {
                                for (int i2 = 0; i2 < planDetailParams.size(); i2++) {
                                    EquipmentUpkeepTaskDetailParam taskDetailParam = new EquipmentUpkeepTaskDetailParam();
                                    taskDetailParam.setNum(planDetailParams.get(i2).getNum());
                                    taskDetailParam.setParam(planDetailParams.get(i2).getParameter());
                                    taskDetailParam.setTaskId(task.getId());
                                    taskDetailParam.setDetailId(taskDetail.getId());
                                    taskDetailParam.setCreateBy("系统生成");
                                    taskDetailParam.setCreateTime(new Date());
                                    tpmUpkeepTaskDetailParamService.save(taskDetailParam);
                                }
                            }
                        }
                    }
                };
                plan.setLastPlanStart(prePlanStartTime);
                plan.setLastPlanEnd(nextPlanStartTime);

                if (nextPlanStartTime.after(tomorrow)) {
                    // 下次计划开始日期超过了明天，就不在生成
                    break;
                }
                prePlanStartTime = nextPlanStartTime;
            }
            tpmUpkeepPlanService.update(plan);
        });

        log.info(" --- 生成保养任务调度结束 --- ");

    }
}
